home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / math / alged34.zip / ALGEDSRC.ZIP / ALGSHOW.C < prev    next >
C/C++ Source or Header  |  1996-06-06  |  15KB  |  583 lines

  1. /*--------------------------------------------------------------------
  2.    Alged:  Algebra Editor    henckel@vnet.ibm.com
  3.  
  4.    Copyright (c) 1994 John Henckel
  5.    Permission to use, copy, modify, distribute and sell this software
  6.    and its documentation for any purpose is hereby granted without fee,
  7.    provided that the above copyright notice appear in all copies.
  8. */
  9. #include "alged.h"
  10. #include <alloc.h>
  11. /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  12.  
  13.     The following functions relate to displaying expressions on the
  14.     screen.
  15. */
  16.  
  17. /*-----------------------------------------------------------------
  18.    twirl - this spins a little status indicator on the bottom
  19.    of the display to reassure the user in long calculations.
  20. */
  21. void twirl(void) {
  22.   static char c[] = "/-\\|";
  23.   static int i=0;
  24.   gotoxy(5,ti.screenheight);
  25.   putch(c[i]);
  26.   if (++i > 3) i=0;
  27. }
  28. /*--------------------------------------------------------------------
  29.    debug dump
  30. */
  31. void dumpnode(node *p,int tab) {
  32.   int i;
  33.   for (i=0; i<tab; ++i) putch(' ');
  34.   cprintf("%p %d %d (%d %d) %d '%s'\r\n",p,p->kind,p->nump,
  35.          p->px,p->py,p->sy,p->name);
  36.   for (i=0; i<p->nump; ++i)
  37.     dumpnode(p->parm[i],tab+2);
  38. }
  39.  
  40. /*--------------------------------------------------------------------
  41.    re compute size of each node
  42. */
  43. void resize(node *p,int ppr) {
  44.   double x;
  45.   int mpr,i;
  46.   mpr = pr[p->kind];
  47.   p->ay = 0;
  48.   switch (p->kind) {
  49.   case NUM:
  50.     x = fabs(p->value);
  51.     p->name[0] = 0;
  52.     if (p->value<0) strcat(p->name,"-");
  53.     if (x==M_PI)       strcat(p->name,piname);
  54.     else if (x==M_E)   strcat(p->name,ename);
  55.     else if (x==HUGE_VAL) strcat(p->name,infname);
  56.     else if (ch8 && x==0.5) strcat(p->name,halfname);
  57.     else if (ch8 && x==0.25) strcat(p->name,qtrname);
  58.     else         sprintf(p->name,"%1.15G",p->value);
  59.     p->sy=1;
  60.     p->sx=strlen(p->name);
  61.     if (!point && strchr(p->name,'.')) *strchr(p->name,'.') = ',';
  62.     break;
  63.   case BAD:
  64.     strcpy(p->name,errname);    /* fall thru */
  65.   case VAR:
  66.     p->sy=1;
  67.     p->sx=strlen(p->name);
  68.     break;
  69.   case EQU:
  70.   case ADD:
  71.   case SUB:
  72.     p->sx = 3;
  73.     if (mpr<ppr) p->sx += 2;         /* parens */
  74.     resize(p->lf,mpr);
  75.     resize(p->rt,mpr+1);         /* +1 = a hack */
  76.     p->sy = max(p->lf->sy,p->rt->sy);
  77.     p->sx += p->lf->sx + p->rt->sx;
  78.     strcpy(p->name,kname[p->kind]);
  79.     break;
  80.   case MUL:
  81.     p->sx = 1;
  82.     if (mpr<ppr) p->sx += 2;         /* parens */
  83.     resize(p->lf,mpr);
  84.     resize(p->rt,mpr+1);         /* +1 = a hack */
  85.     p->sy = max(p->lf->sy,p->rt->sy);
  86.     p->sx += p->lf->sx + p->rt->sx;
  87.     strcpy(p->name,kname[p->kind]);
  88.     break;
  89.   case DIV:
  90.     resize(p->lf,1);       /* 1 = div suppresses parens */
  91.     resize(p->rt,1);
  92.     p->sx = max(p->lf->sx,p->rt->sx) + 2;
  93.     p->sy = p->lf->sy + p->rt->sy + 1;
  94.     p->ay = p->lf->sy - p->rt->sy;
  95.     if (p->ay <0) p->ay--;
  96.     p->ay /= 2;
  97.     if (mpr<ppr) p->sx += 2;         /* parens */
  98.     strcpy(p->name,kname[p->kind]);
  99.     break;
  100.   case EXP:
  101.     resize(p->lf,mpr+1);
  102.     resize(p->rt,mpr);
  103.     p->sx = p->lf->sx + p->rt->sx;
  104.     p->sy = p->lf->sy + p->rt->sy;
  105.     p->ay = p->rt->sy - p->lf->sy;
  106.     if (p->ay >0) p->ay++;
  107.     p->ay /= 2;
  108.     if (mpr<ppr) p->sx += 2;         /* parens */
  109.     strcpy(p->name,kname[p->kind]);
  110.     break;
  111.   case FUN:
  112.     p->sx = strlen(p->name) + 1;     /* 2 parens JDH check this! */
  113.     p->sy = 0;
  114.     for (i=0; i<p->nump; ++i) {
  115.       resize(p->parm[i],mpr);
  116.       setmax(p->sy,p->parm[i]->sy);
  117.       p->sx += 1 + p->parm[i]->sx;     /* 1 comma */
  118.     }
  119.     break;
  120.   default:
  121.     printf(msg[14]);
  122.     pause;
  123.   }
  124. }
  125. /*--------------------------------------------------------------------
  126.    leftpar - print a left parenthesis
  127. */
  128. void leftpar(int h) {
  129.   int i;
  130.   if (h<2) {
  131.     putch('('); return; }
  132.   relxy(0,-h/2);
  133.   putch(ulc);
  134.   for (i=0; i<h-2; ++i) {
  135.     relxy(-1,1);
  136.     putch(vline);
  137.   }
  138.   relxy(-1,1);
  139.   putch(llc);
  140. }
  141. /*--------------------------------------------------------------------
  142.    rightpar - print a right parenthesis
  143. */
  144. void rightpar(int h) {
  145.   int i;
  146.   if (h<2) {
  147.     putch(')'); return; }
  148.   relxy(0,-h/2);
  149.   putch(urc);
  150.   for (i=0; i<h-2; ++i) {
  151.     relxy(-1,1);
  152.     putch(vline);
  153.   }
  154.   relxy(-1,1);
  155.   putch(lrc);
  156. }
  157. /*-----------------------------------------------------------------
  158.    fix attributes
  159. */
  160. int fixattr(node *p) {
  161.   gettextinfo(&ti);
  162.   if (p==src) textattr(bold1);
  163.   return ti.attribute;
  164. }
  165.  
  166. #define seen (x > 0 && x < ti.screenwidth)
  167.  
  168. /*--------------------------------------------------------------------
  169.    print expression
  170. */
  171. void show(node *p,int ppr,int x,int y) {
  172.   int mpr,i,z,s0,s1,attr;
  173.   mpr = pr[p->kind];
  174.  
  175.   if (yadj) y = y + p->ay;           /* adjust y */
  176.   gotoxy(x,y);
  177.   attr=fixattr(p);         /* save old attribute */
  178.  
  179.   switch (p->kind) {
  180.   case NUM:
  181.   case BAD:
  182.   case VAR:
  183.     p->px = x; p->py = y;
  184.     i = strlen(p->name); z = 0;
  185.     if (x > ti.screenwidth) break;
  186.     if (i+x > ti.screenwidth) i = ti.screenwidth - x;
  187.     if (x < 1) { gotoxy(1,y); z = -x; }
  188.     if (z < i) cprintf("%.*s",i-z,p->name+z);
  189.     break;
  190.   case EQU:
  191.   case ADD:
  192.   case SUB:
  193.     if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; }     /* parens */
  194.     show(p->lf,mpr,x,y);
  195.     x += p->lf->sx + 1;
  196.     gotoxy(x-1,y);
  197.     fixattr(p);
  198.     if (seen) cprintf(" %s ",kname[p->kind]);
  199.     show(p->rt,mpr+1,x+2,y);
  200.     p->px = x; p->py = y;
  201.     if (mpr<ppr) {
  202.       x += 2+p->rt->sx;
  203.       gotoxy(x,y);
  204.       fixattr(p);
  205.       if (seen) rightpar(p->sy);                 /* parens */
  206.     }
  207.     break;
  208.   case MUL:
  209.     if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; }     /* parens */
  210.     show(p->lf,mpr,x,y);
  211.     x += p->lf->sx;
  212.     gotoxy(x,y);
  213.     fixattr(p);
  214.     if (seen) cputs(ch8 ? kname[p->kind] : "*");
  215.     show(p->rt,mpr+1,x+1,y);
  216.     p->px = x; p->py = y;
  217.     if (mpr<ppr) {
  218.       x += 1+p->rt->sx;
  219.       gotoxy(x,y);
  220.       fixattr(p);
  221.       if (seen) rightpar(p->sy);                 /* parens */
  222.     }
  223.     break;
  224.   case DIV:
  225.     if (seen) for (i=0; i<p->sx; ++i) {
  226.       if (x+i < ti.screenwidth) putch(hline);
  227.     }
  228.     else if (x<1 && 0<(i=x+p->sx)) {
  229.       gotoxy(1,y); while (--i) putch(hline);
  230.     }
  231.     p->px = x; p->py = y;
  232.     if (mpr<ppr) {
  233.       gotoxy(x,y);
  234.       if (seen) leftpar(p->sy);       /* parens */
  235.     }
  236.     show(p->lf,1,x + (p->sx - p->lf->sx)/2,
  237.                       y - (p->lf->sy + 1)/2);
  238.     fixattr(p);
  239.     show(p->rt,1,x + (p->sx - p->rt->sx)/2,
  240.                       y + (p->rt->sy + 2)/2);
  241.     if (mpr<ppr) {
  242.       x+=p->sx-1;
  243.       gotoxy(x,y);
  244.       fixattr(p);
  245.       if (seen) rightpar(p->sy);         /* parens */
  246.     }
  247.     break;
  248.   case EXP:
  249.     if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; }     /* parens */
  250.     show(p->rt,mpr  ,x + p->lf->sx,y - (p->rt->sy + 1)/2);
  251.     fixattr(p);
  252.     show(p->lf,mpr+1,x,            y + (p->lf->sy + 0)/2);
  253.     p->px = x + p->lf->sx - 1;
  254.     p->py = y - 1;
  255.     if (mpr<ppr) {
  256.       x += p->sx-2;
  257.       gotoxy(x,y);
  258.       fixattr(p);
  259.       if (seen) rightpar(p->sy);         /* parens */
  260.     }
  261.     break;
  262.   case FUN:
  263.     p->px = x; p->py = y;
  264.     if (seen) {
  265.       cputs(p->name);
  266.       leftpar(p->sy);
  267.     }
  268.     x += strlen(p->name) + 1;
  269.     for (i=0; ; ) {
  270.       show(p->parm[i],mpr,x,y);
  271.       x += p->parm[i]->sx;
  272.       gotoxy(x,y);
  273.       fixattr(p);
  274.       if (++i >= p->nump) break;
  275.       if (seen) putch(comma);
  276.       ++x;
  277.     }
  278.     if (seen) rightpar(p->sy);         /* parens */
  279.     break;
  280.   default:
  281.     printf(msg[15]);
  282.     pause;
  283.   }
  284.   textattr(attr);
  285. }
  286. /*-----------------------------------------------------------------
  287.    This test the integrity of the heap and returns the amount of
  288.    space USED.
  289. */
  290. long heapused() {
  291.   struct heapinfo hi;  long t=0;
  292.   if (heapcheck()<0) {
  293.     printf(msg[28]); pause;
  294.     return -1;
  295.   }
  296.   hi.ptr=NULL;
  297.   while (heapwalk(&hi)==2)
  298.     if (hi.in_use) t+=hi.size;
  299.   return t;
  300. }
  301.  
  302. /*------------------------------------------------------------